<?php
/***
 * Name:	AlexSnet's framework MVC
 * About:	An MVC application framework for PHP
 * Copyright:	(C) 2008, Sudo me.
 * Author:	Alex Snet, me [at] alexsnet [dot] ru
 * Site:	http://alexsnet.ru/
 ***/

// ------------------------------------------------------------------------

if(!defined('ASMVC_VERSION'))
  define('ASMVC_VERSION','1.0.5');
  
// ------------------------------------------------------------------------

$ASfMVC_IncludePATH = array(
	ASMVC_BASEDIR . 'sysfiles' . DS . 'plugins',
	ASMVC_BASEDIR . 'myfiles' . DS . 'plugins',
	ASMVC_MYAPPDIR . 'plugins'
);

// ------------------------------------------------------------------------

/**
 * ASMVC
 *
 * main object class
 *
 * @package		ASfMVC
 * @author		Alex Snet
 */

class ASMVC
{
	/**
	 * instance
	 *
	 * get/set the ASMVC object instance
	 *
	 * @access	public
	 * @param   object $new_instance reference to new object instance
	 * @return  object $instance reference to object instance
	 */    
	public static function &instance($new_instance=null)
	{
	  static $instance = null;
	  if(isset($new_instance))
	    $instance = $new_instance;
	  return $instance;
	}
}

/**
 * ASMVC_Add_Path
 *
 * add a new path to find classes in
 *
 * @access	public
 * @param   string $path path to find in
 * @return  boolean  success or failure
 */    
function ASMVC_Add_Path($path)
{
	if(is_dir($path))
	{
		if(!in_array($path,$GLOBALS['ASfMVC_IncludePATH']))
			$GLOBALS['ASfMVC_IncludePATH'][] = $path; 
		return true;
	}
	return false;
}

/**
 * __autoload
 *
 * auto-load internal plugin classes
 *
 * @access	public
 * @param   string $class_name the class name we are trying to load
 * @return  boolean  success or failure
 */    
function __autoload($class_name)
{
	$filepath = false;
	foreach($GLOBALS['ASfMVC_IncludePATH'] as $path)
	{
		if($filepath and file_exists($filepath)) continue;
		$filepath = $path . DS . $class_name . '.php';
		if(!file_exists($filepath))
			$filepath = $path . DS . 'internal.' . $class_name . '.php';
		if(!file_exists($filepath))
			$filepath = $path . DS . $class_name . '.class.php';
		if(!file_exists($filepath))
			$filepath = $path . DS . $class_name . DS . $class_name . '.php';
	}
  if(!file_exists($filepath))
    return false;
  return require_once $filepath;
}

/**
 * ASMVC_error_handler
 *
 * the internal error handler function
 *
 * @access	public
 */    
function ASMVC_error_handler($errno, $errstr, $errfile, $errline)
{

  include(ASMVC_MYAPPDIR . 'configs' . DS . 'application.php');

  $errors =& new $config['error_handler_class'];
  $errors->trigger_error($errno, $errstr, $errfile, $errline);

  /* don't execute PHP internal error handler */
  return true;
  
}

/* define myapp directory */
if(!defined('ASMVC_MYAPPDIR'))
  define('ASMVC_MYAPPDIR', ASMVC_BASEDIR . 'myapp' . DS);

/* include application config */
include(ASMVC_MYAPPDIR . 'configs' . DS . 'application.php');

/* get controller/method from path_info,
   use defaults if none given */
if(!defined('ASMVC_REQUEST_URI'))
  define('ASMVC_REQUEST_URI',trim($_SERVER['REQUEST_URI'],'/'));
$path_info = explode('/',ASMVC_REQUEST_URI);
//$controller = !empty($path_info[0]) ? preg_replace('!\W!','',$path_info[0]) : $config['default_controller'];
$controller = empty($path_info[0])?$config['default_controller']:$path_info[0];
$controller_file = ASMVC_MYAPPDIR . DS . 'controllers' . DS . $controller .'.php';

/* see if controller exists */
if(!file_exists($controller_file))
{
  //trigger_error("Unknown controller file '{$controller}'",E_USER_ERROR);
  $controller = 'error';
  $controller_file = ASMVC_MYAPPDIR . DS . 'controllers' . DS . 'error.php';
  if(!file_exists($controller_file))
	$controller_file = ASMVC_BASEDIR . 'sysfiles' . DS . 'controllers' . DS . 'error.php';
	
}
include($controller_file);

/* see if controller class exists */
$controller_class = $controller.'_Controller';
if(!class_exists($controller_class))
  trigger_error("Unknown controller class '{$controller_class}'",E_USER_ERROR);
  
$ASMVC = new $controller_class(true);

set_error_handler('ASMVC_error_handler');

/* see if controller class method exists */
$controller_method = !empty($path_info[1]) ? $path_info[1] : 'index';

/* cannot call method names starting with underscore */
if(substr($controller_method,0,1)=='_')
  trigger_error("Private method name not allowed '{$controller_method}'",E_USER_ERROR);

/* cannot call reserved method names */
if(in_array($controller_method,array('view','assign','fetch')))
  trigger_error("Reserved method name not allowed '{$controller_method}'",E_USER_ERROR);

include(ASMVC_MYAPPDIR . 'configs' . DS . 'autoload.php');

/* auto-load libraries */
if(!empty($config['libraries']))
{
  foreach($config['libraries'] as $library)
    if(is_array($library))
      $ASMVC->load->library($library[0],$library[1]);
    else
      $ASMVC->load->library($library);
}

/* auto-load scripts */
if(!empty($config['scripts']))
{
  foreach($config['scripts'] as $script)
    $ASMVC->load->script($script);
}
  
/* execute method */
if(method_exists($ASMVC,$controller_method) and $controller!='error') $ASMVC->$controller_method($path_info);
elseif($controller=='error') $ASMVC->index();
else
{
	//trigger_error("Unknown controller method '{$controller_method}'",E_USER_ERROR);
	$controller = 'error';
	$controller_class = $controller.'_Controller';
	$controller_file = ASMVC_MYAPPDIR . DS . 'controllers' . DS . 'error.php';
	if(!file_exists($controller_file)) $controller_file = ASMVC_BASEDIR . 'sysfiles' . DS . 'controllers' . DS . 'error.php';
	include($controller_file);
	
	$ERR = new $controller_class(true);
	$ERR->index();
}
?>